<?php
namespace app\api\model;
class WorkTime
{
    // 定义工作日 [1, 2, 3, 4, 5, 6, 0]
    public $week_workingday = [1, 2, 3, 4, 5];
    
    // 定义上下班时间
    public $on_duty_time = '9:00:00';
    public $off_duty_time = '18:00:00';
    
    //每天工作时长
    public $oneday_hours = 8;
    
    public function __construct()
    {
        if (empty($this->oneday_hours)) {
            $this->oneday_hours = $this->off_duty_time - $this->on_duty_time;
        }
    }
    
    
    public function get_working_hours(int $start_time, int $over_time)
    {
        // 如果工作日列表为空 返回0
        $workingdays = $this->workingdays($start_time, $over_time);
        
        if (empty($workingdays)) {
            return 0;
        }
        
        // 如果开始时间不是工作日,将开始时间调整为第一个工作日的上班时间
        // 如果截止时间不是工作日,将开始时间调整为最后一个工作日的下班时间
        if (!in_array(date('Y/m/d', $start_time), $workingdays)) {
            $start_time = strtotime($workingdays[0] . ' ' . $this->on_duty_time);
        }
        
        if (!in_array(date('Y/m/d', $over_time), $workingdays)) {
            $over_time = strtotime(end($workingdays) . ' ' . $this->off_duty_time);
        }
        
        // 如果开始时间与截止时间是同一天,直接计算
        // 反之分别计算开始时间与截止时间
        if (date('Y/m/d', $start_time) == date('Y/m/d', $over_time)) {
            $sec = $over_time - $start_time;
            if ($sec > 3600 * $this->oneday_hours) {
                $sec = 3600 * $this->oneday_hours;
            }
            // 昨天到了计算秒数
        } else {
            // 计算开始日工作时间
            $start_day_sec = strtotime($workingdays[0] . ' ' . $this->off_duty_time) - $start_time;
            if ($start_day_sec > 3600 * $this->oneday_hours) {
                $start_day_sec = 3600 * $this->oneday_hours;
            }
            // 计算截止日工作时间
            $over_day_sec = $over_time - strtotime(end($workingdays) . ' ' . $this->on_duty_time);
            if ($over_day_sec > 3600 * $this->oneday_hours) {
                $over_day_sec = 3600 * $this->oneday_hours;
            }
            
            $all_day_sec = ((count($workingdays) - 2) * $this->oneday_hours) * 3600;
            $sec         = $start_day_sec + $over_day_sec + $all_day_sec;
        }
        
        return $sec / (3600*8);
    }
    
    # 计算工作日(包含开始与截止日期)
    protected function workingdays($start_time, $over_time)
    {
        $start_time = strtotime('-1 day', $start_time);
        $over_time  = strtotime('-1 day', $over_time);
        
        $new_workingdays = $this->new_workingdays();
        $new_holidays    = $this->new_holidays();
        $workingdays     = [];
        
        while ($start_time < $over_time) {
            $start_time     = strtotime('+1 day', $start_time);
            $is_holidays    = in_array(date('w', $start_time), $this->week_workingday) && !in_array(date('Y/m/d', $start_time), $new_holidays);
            $is_workingdays = in_array(date('Y/m/d', $start_time), $new_workingdays);
            
            if ($is_holidays || $is_workingdays) {
                $workingdays[] = date('Y/m/d', $start_time);
            }
        }
        
        return $workingdays;
    }
    
    
    # 新增工作日
    protected function new_workingdays()
    {
        $days = [
            '2022/01/21',
            '2023/01/29',
            '2023/04/01',
            '2023/04/02',
            '2023/04/23',
            '2023/05/06',
            '2023/06/25',
            '2023/06/25',
            '2023/10/08',
        ];
        
        return $days;
    }
    
    # 新增休息日
    protected function new_holidays()
    {
        $days = [
            '2022/12/30',
            '2022/12/31',
            '2023/01/01',
            '2023/01/22',
            '2023/01/23',
            '2023/01/24',
            '2023/01/25',
            '2023/01/26',
            '2023/01/27',
            '2023/01/28',
            '2023/02/03',
            '2023/02/04',
            '2023/02/05',
            '2023/04/03',
            '2023/04/04',
            '2023/04/05',
            '2023/04/29',
            '2023/04/30',
            '2023/05/01',
            '2023/05/02',
            '2023/05/03',
            '2023/06/22',
            '2023/06/23',
            '2023/06/24',
            '2023/09/29',
            '2023/09/30',
            '2023/10/01',
            '2023/10/02',
            '2023/10/03',
            '2023/10/04',
            '2023/10/05',
            '2023/10/06',
            '2023/10/07',
        ];
        
        return $days;
    }
    
}